﻿#include <QTextCodec>
#include <sys/types.h>
//#include <sys/socket.h>
#include "socketsend.h"

socketsend::socketsend(QObject *parent)
    : QThread(parent)
{
    abort = false;
    pTimer = NULL;
}

socketsend::~socketsend(){
    //qDebug()<<pthread<<"thread abort";
    emit threadexit(pthread);
}

void socketsend::startTimer(int ntime){
    if(pTimer==NULL){
        pTimer = new QTimer(this);
        connect(pTimer,SIGNAL(timeout()),this,SLOT(overtime()));
        pTimer->setSingleShot(true);
        pTimer->start(ntime);
    }
    else{
        pTimer->start(ntime);
    }
}

void socketsend::overtime(){
    qDebug()<<"Timer out of";
    killTimer();
    exit();
    emit getData(pthread,99,QStringLiteral("等待接收返回数据超时!"));
}

void socketsend::killTimer(){
    if(pTimer!=NULL){
        delete pTimer;
        pTimer = NULL;
    }
}

void socketsend::requestData(int ph,const QString &hostName, quint16 port,int type,QByteArray data)
{
    QMutexLocker locker(&mutex);

    this->pthread = ph;
    this->hostName = hostName;
    this->port = port;
    this->data = data;
    this->m_type = type;
    abort = false;
    //qDebug()<<hostName<<port;

    start();
}

void socketsend::exit(){
    mutex.lock();
    abort = true;
    mutex.unlock();
}

void socketsend::run()
{
    //QString pagedata = QString("@@%1\n").arg(data.size()+5,5,10,QLatin1Char('0'));
    QString pagedata = QString("@@%1%2|").arg(data.size()+11,4,10,QLatin1Char('0')).arg(m_type,4,10,QLatin1Char('0'));
    data.append('\n');

    data.insert(0,pagedata.toUtf8());
    QTcpSocket socket;

    //QString qdata = data;

    const int Pertime = 2000;
    const int Timeout = 2*Pertime;

    QByteArray by;

    int x=0;

cc1:
    if(abort){
        return;
    }

    socket.connectToHost(hostName, port);
    if (!socket.waitForConnected(Pertime)) {
        if(x>Timeout){
            emit error(pthread,socket.error(), socket.errorString());
            return;
        }
        else{
            x+=Pertime;
            //qDebug()<<pthread<<"wait for connect:"<<x;
            goto cc1;
        }
    }

    if(abort){
        return;
    }

    qDebug()<<"write:"<<data;

    socket.write(data);

    while(1){
        if (!socket.waitForReadyRead(Pertime*5)) {
            killTimer();
            int index = by.indexOf('\n');
            if(-1 == index){
                emit error(pthread,socket.error(), socket.errorString());
            }
            else{
                QByteArray line = by.left(index);
                if(!line.startsWith("@@")){
                    qWarning()<<"Error Start";
                }
                if(line.mid(2,4).toInt()!=line.size()){
                    qWarning()<<"Error data length";
                    return;
                }
                if(line.mid(6,4).toInt()!=1){
                    emit getData(pthread,0,QString::fromUtf8(line.right(line.size()-10)));//fail
                }
                else{
                    emit getData(pthread,1,QString::fromUtf8(line.right(line.size()-10)));//success
                }
            }
            return;
        }
        else{
            by += socket.readAll();

            int index = by.indexOf('\n');
            if(-1 == index){
                startTimer(6000);
            }
            else{
                killTimer();

                QByteArray line = by.left(index);
                if(!line.startsWith("@@")){
                    qWarning()<<"Error Start:"<<line;
                    return;
                }
                if(line.mid(2,4).toInt()!=line.size()){
                    qWarning()<<"Error data length:"<<line;
                    return;
                }
                if(line.mid(6,4).toInt()!=1){
                    emit getData(pthread,0,QString::fromUtf8(line.right(line.size()-10)));//fail
                }
                else{
                    emit getData(pthread,1,QString::fromUtf8(line.right(line.size()-10)));//success
                }

                return;
            }
        }

        if(abort){
            return;
        }
    }

    //socket.disconnectFromHost();
    //socket.waitForDisconnected();
}
